//
//  NetNode.swift
//  soapp_Example
//
//  Created by zhu xietong on 2018/2/12.
//  Copyright © 2018年 CocoaPods. All rights reserved.
//

import Foundation
import AsyncDisplayKit
import Kingfisher



class KfImageCache: NSObject,ASImageCacheProtocol, ASImageDownloaderProtocol  {
    
    static let shared = KfImageCache()
    
    func cachedImage(with URL: URL, callbackQueue: DispatchQueue, completion: @escaping ASImageCacherCompletion) {
        UIImage.kf_cache(url: URL.absoluteString) { (img) in
            completion(img, .asynchronous)
        }
//        if let img = UIImage.kf_cache(url: URL.absoluteString)
//        {
//            completion(img, .asynchronous)
//        }
//        else{
//            completion(nil, .asynchronous)
//
//        }
    }
    
    func cancelImageDownload(forIdentifier downloadIdentifier: Any) {
        if let task = downloadIdentifier as? DownloadTask
        {
            task.cancel()
        }
    }
    
    
    func downloadImage(with URL: URL, callbackQueue: DispatchQueue, downloadProgress: ASImageDownloaderProgress?, completion: @escaping ASImageDownloaderCompletion) -> Any? {
        //         [.transition(ImageTransition.fade(0.5))]
        
        let task = KingfisherManager.shared.retrieveImage(with: URL, options: nil, progressBlock: { (received, expected) in
            let progress = expected == 0 ? 0 : received / expected
            downloadProgress?(CGFloat(progress))
        }, downloadTaskUpdated: nil) { (result) in
                
            switch result{
            case .success(let res):
                completion(res.image,nil,nil,nil)
                break
            case .failure(let error):
                completion(nil,error,nil,nil)

                break
            }
        }
//        let task = KingfisherManager.shared.retrieveImage(with: URL, options: nil, progressBlock: { (received, expected) in
//            let progress = expected == 0 ? 0 : received / expected
//            downloadProgress?(CGFloat(progress))
//        }) { (img, err, cacheType, url) in
//            completion(img, err, nil, nil)
//        }
        return task
    }
    
    
    
    
}

extension ASNetworkImageNode {
    static func imageNode() -> ASNetworkImageNode {
        let manager = KfImageCache.shared
        let node = ASNetworkImageNode(cache: manager, downloader: manager)
        node.placeholderColor = UIColor.table_bg_color
        return node
    }
}

extension UIImage
{
    public static func kf_cache(url:String,finish:@escaping(UIImage?)->Void){
        let img = ImageCache.default.retrieveImageInMemoryCache(forKey: url)
        if img == nil{
       
            ImageCache.default.retrieveImageInDiskCache(forKey: url) { (result) in
                switch result {
                case .success(let value):
                
                    if let img = value?.images?.first{
                        finish(img)
                    }else{
                        finish(nil)
                    }
                    
                    
//                        print("Task done for: \(value.source.url?.absoluteString ?? "")")
                    case .failure(let error):
                        finish(nil)
                        print("Job failed: \(error.localizedDescription)")
                }
                
            }
            
//            img = ImageCache.default.retrieveImageInDiskCache(forKey: url)
        }else{
            finish(img)
        }
    }
}




let __holderImg = UIImage(named:"iwe_gray_holder_300")
open class JoImageNode1: ASDisplayNode {
    public var networkImageNode = ASNetworkImageNode.imageNode()
    public var imageNode = ASImageNode()
    
    
    
    public var placeholderColor: UIColor? {
        didSet {
            networkImageNode.placeholderColor = placeholderColor
        }
    }
    
    public var image: UIImage? {
        didSet {
            
            networkImageNode.image = image
        }
    }
    
    open override var placeholderFadeDuration: TimeInterval {
        didSet {
            networkImageNode.placeholderFadeDuration = placeholderFadeDuration
        }
    }
    
    public var placeholderImg:UIImage? = __holderImg
    
    open var url: URL? {
        didSet {
            networkImageNode.defaultImage = placeholderImg
            imageNode.image = nil
//            guard let _ = url,let image = UIImage.kf_cache(url:url?.absoluteString ?? "") else {
//                networkImageNode.url = url
//                return
//            }
            guard let url_ = url?.absoluteString else{
                networkImageNode.url = url
                return
            }
            
            UIImage.kf_cache(url: url_) {[weak self] (img) in
                if let _ = img{
                    self?.imageNode.image = img

                }else{
                    
                    self?.networkImageNode.url = self?.url
                }
            }
        }
    }
    
    public override init() {
        super.init()
        placeholderFadeDuration = 0.5
        addSubnode(networkImageNode)
        addSubnode(imageNode)
    }
    
    override open func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
        return ASInsetLayoutSpec(insets: .zero,
                                 child: networkImageNode.url == nil ? imageNode : networkImageNode)
    }
    
    public func addTarget(_ target: Any?, action: Selector, forControlEvents controlEvents: ASControlNodeEvent) {
        networkImageNode.addTarget(target, action: action, forControlEvents: controlEvents)
        imageNode.addTarget(target, action: action, forControlEvents: controlEvents)
    }
    
    
    public var img_url: String = ""{
        didSet{
            if img_url.len < 1
            {
                self.url = nil
            }
            if let url = URL(string:img_url)
            {
                self.url = url
            }
            else{
                self.url = nil
            }
        }
    }
    
    deinit {
    }
    
}

open class JoButton: ASDisplayNode {
    
    public static var total:Int = 0
    
    public var button = UIButton()
    
    
    public override init() {
        super.init()
    }
    
    open override func didLoad() {
        super.didLoad()
        view.addSubview(button)
    }
    
    open override func layout() {
        super.layout()
        button.frame = self.bounds
//        button.backgroundColor = .red
    }
    
 
    
    deinit {
       
    }

    
}


extension JoImageNode{
    
    public var ui:ImageViewStyle{
        get{
            if let style = __style["ui"] as? ImageViewStyle{
                return style
            }
            let style = ImageViewStyle()
            style.holder(type: .grayBack)
            __style["ui"] = style
            return style
        }
    }
}



open class JoImageNode: ASDisplayNode {
    open func mo_will_display() {
        imageView?.img_url = image_url_
    }
    open func mo_end_display() {
        image = nil
    }
    
    public static var total:Int = 0
    
    public var imageView:UIImageView? = nil
    
    public var completionHandler:KFCompletionHandler? = nil
    
    public override init() {
        super.init()
        JoImageNode.total = JoImageNode.total + 1
//        print("init JoImageNode \(JoImageNode.total)")
        
    }
    
    
    open override func didLoad() {
        super.didLoad()
        let imgV = UIImageView()
        if let img = image{
            imgV.image = img
        }
        imgV.ui = self.ui
        isUserInteractionEnabled = false

        if let hander = completionHandler{
            imgV.completionHandler = hander
        }
        view.addSubview(imgV)
        imageView = imgV
    }
  
    open override func layout() {
        super.layout()
        imageView?.frame = self.bounds
        if img_url.len > 0
        {
            imageView?.img_url = img_url
        }
    }
    
    public var image:UIImage? = nil{
        didSet{
            imageView?.image = image
        }
    }
    var image_url_ = ""
    public var img_url: String = ""{
        didSet{
            
            image_url_ = img_url
            imageView?.img_url = img_url
        }
    }
    
    public var src:Any? = ""{
        didSet{
            if let url_ = src as? String{
                self.img_url = url_
                return
            }
            if let img = src as? UIImage{
                self.image = img
                return
            }
            self.image = nil
            
        }
      
       
    }
    
    deinit {
        JoImageNode.total = JoImageNode.total - 1
//        print("deinit JoImageNode \(JoImageNode.total)")
    }
    
//    override open func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
//        //        mf.spec = self.specGetter()
//        //        let spec = super.layoutSpecThatFits(constrainedSize)
//        //
//        //        if let list = spec.subSpec(specId: "list") as? ASStackLayoutSpec
//        //        {
//        //            list.children =  nodes
//        //        }
//
//        print("===layoutSpecThatFits|\(constrainedSize)")
//
//
//        return super.layoutSpecThatFits(constrainedSize)
//    }
    
    
}





open class JoImageNode2: ASNetworkImageNode {
    public init()
    {
        super.init(cache: KfImageCache.shared, downloader: KfImageCache.shared)
        self.placeholderFadeDuration = 0.12
    }
    
 
    public var img_url: String = ""{
        didSet{
            if img_url.len < 1
            {
                self.url = nil
            }
            if let url = URL(string:img_url)
            {
                weak var wself = self;
                UIImage.kf_cache(url: img_url) { (img) in
                    if let image = img{
                        wself?.defaultImage = image
                    }else{
                        wself?.url = url

                    }
                }
//                guard let image = UIImage.kf_cache(url:img_url) else {
//                    self.url = url
//                    return
//                }
                self.defaultImage = image
            }
            else{
                self.url = nil
            }
        }
    }
    
    deinit {
    }
    
}



